import main.*;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;



public class main {

	public static void main(String[] args) {
		
		boolean release = false;
		StopwordEnglish swe = new StopwordEnglish();
		Stemmer stemmer = new Stemmer();
		String text1;
		String text2;

		ArrayList<indieces> dict = new ArrayList<indieces>();
		AVLTree<FinalIDX> finalDict = new AVLTree<FinalIDX>();
		//BTree <FinalIDX> finalDict = new BTree<FinalIDX>();
		
		//File reader
		if(release)
		{
			text1 = readFile("Macaria.txt");
			text2 = readFile("TheMabinogion.txt");
			if(text1 == null)
				Out.println("Fehler beim lesen");
		} else {
			System.out.println("Ersten Text eingeben!");
			text1 = In.readLine();
			System.out.println("Zweiten Text eingeben!");
			text2 = In.readLine();
		}
		int skipStepWidth = 1;
		
		Out.println("lesen fertig");
		
		// Aufsplitten
		StringTokenizer st = new StringTokenizer(text1);

		while (st.countTokens() > 0) {
			String a = st.nextToken();
			if(!swe.isStopword(a))
			{
				char[] stemword = a.toCharArray();
				stemmer.add(stemword, stemword.length);
				stemmer.stem();
				String stemmed = stemmer.toString();
				
				indieces j = new indieces(stemmed, 1);
				//Out.println(stemmed);
				dict.add(j);
			} else {
				//Out.println("Stopwort "+a+" erkannt");
			}
		}
		
		Out.println("Tokenizer und stemmer 1 fertig");
		
		st = new StringTokenizer(text2);

		while (st.countTokens() > 0) {
			String a = st.nextToken();
			if(!swe.isStopword(a))
			{
				char[] stemword = a.toCharArray();
				stemmer.add(stemword, stemword.length);
				stemmer.stem();
				String stemmed = stemmer.toString();
				
				indieces j = new indieces(stemmed, 2);
				dict.add(j);
			}else {
				//Out.println("Stopwort "+a+" erkannt");
			}
		}
		

		Out.println("Tokenizer und stemmer 2 fertig");
		

		System.out.println(dict.size());

		java.util.Collections.sort(dict);

		FinalIDX letzter = null;
		for (int i = 0; i < dict.size(); i++) {
			if (i == 0) {
				letzter = new FinalIDX(dict.get(i).name,
						dict.get(i).documents);
				finalDict.insert(letzter);
			} else {
				String name = dict.get(i).name;
				String le = letzter.name;
				if (name.equals(le)) {
					//Out.println("Add doc: "+name+" "+dict.get(i).documents);
					letzter.addDocument(dict.get(i).documents);
				} else {
					letzter = new FinalIDX(dict.get(i).name, dict.get(i).documents);
					finalDict.insert(letzter);
				}
			}
		}
		
		skipStepWidth = determineSkipWidth(finalDict);
		

		// Frage eingeben
		Out.println("Was willst du suchen?");
		String query = In.readLine();
		String query2 = "";
		boolean term1neg = false;
		boolean term2neg = false;
		// And = + Or = -
		int idx = -1;
		if (query.contains("+")) {
			idx = query.indexOf("+");
			query2 = "+";
		}
		if (query.contains("-")) {
			idx = query.indexOf("-");
			query2 = "-";
		}

		String term1 = query.substring(0, idx - 1);
		String term2 = query.substring(idx + 2, query.length());

		if (term1.contains("!")) {
			term1neg = true;
			term1.replace("!", "");
		}
		if (term2.contains("!")) {
			term2neg = true;
			term1.replace("!", "");
		}

		Out.println(term1);
		Out.println(term2);

		// Schauen was oefter vorkommt
		int fTerm1 = 0;
		int fTerm2 = 0;
		//FinalIDX IdxTerm1 = null;
		//FinalIDX IdxTerm2 = null;

		FinalIDX IdxTerm1 = getFinalIDXofTerm(term1, finalDict, skipStepWidth);
		FinalIDX IdxTerm2 = getFinalIDXofTerm(term2, finalDict, skipStepWidth);
		if(IdxTerm1 != null){
			fTerm1 = IdxTerm1.frequency;
		}
		if(IdxTerm2 != null){
			fTerm2 = IdxTerm2.frequency;
		}
		
	
		
		ArrayList<Integer> foundDocs = new ArrayList<Integer>();
		if (query2.equals("+")) {
			if (IdxTerm1 == null || IdxTerm2 == null) {
				Out.println("Es gibt einen Term nicht!");
			}else{
				Integer[] a = new Integer[100000];
				Integer[] doc1 = IdxTerm1.documents.toArray(a);
				Integer[] doc2 = IdxTerm2.documents.toArray(a);
				if (fTerm1 < fTerm2) {
					for (int i = 0; i < fTerm1; i++) {
						int actDoc1 = doc1[i];
						for (int j = 0; j < fTerm2; j++) {
							int actDoc2 = doc2[j];
							if (actDoc1 == actDoc2) {
								foundDocs.add(actDoc1);
							}
						}
					}
				} else {
					for (int i = 0; i < fTerm2; i++) {
						int actDoc2 = doc2[i];
						for (int j = 0; j < fTerm1; j++) {
							int actDoc1 = doc1[j];
							if (actDoc1 == actDoc2) {
								foundDocs.add(actDoc2);
							}
						}
					}
				}
				
			}
		} 
		else if (query2.equals("-")) {
//			for (int i = 0; i < finalDict.size(); i++) {
//				FinalIDX a = finalDict.get(i);
//				if (a.name.equals(term1) || a.name.equals(term2)) {
//					Integer[] b = new Integer[100];
//					Integer[] doc1 = a.documents.toArray(b);
//					for (int j = 0; j < doc1.length; j++) {
//						if (doc1[j] != null) {
//							foundDocs.add(doc1[j]);
//						}
//					}
//				}
//			}
		}

		// Ausgabe der gefundenen Dokumente
		Out.println(query + " wurde " + foundDocs.size() + " mal gefunden!");
		Out.print("Gefunden in: ");
		for (int i = 0; i < foundDocs.size(); i++) {
			Out.print(foundDocs.get(i) + ",");
		}
		Out.println();

		// Ausgabe
//		for (int i = 0; i < finalDict.size(); i++) {
			finalDict.PrintTree();
//			Out.print("Word: " + j.name + " | Entries: " + j.frequency
//					+ " | Documents: ");
//			for (int k = 0; k < j.frequency; k++) {
//				if (k > 0) {
//					Out.print(",");
//				}
//				//Out.print(((Object) j.documents).poll());
//			}
//			Out.println();
//		}

	}

	private static FinalIDX getFinalIDXofTerm(String term,
			AVLTree<FinalIDX> finalDict, int skipStepWidth) {
		
//		int size = finalDict.size();
//		int rest = size % skipStepWidth;
//		int k;
//		for(k = 0; k < size-rest; k+=skipStepWidth){
//			FinalIDX j = finalDict.get(k);
//			int comp = j.name.compareTo(term);
//			
//			if(comp > 0){
//				//term ist > als j.name also in die Schleife
//				for (int i = k-skipStepWidth; i < i+skipStepWidth; i++){
//					FinalIDX l = finalDict.get(k);
//					if(l.name.equals(term)){
//						return l;
//					}
//				}
//				//dann isses wohl nich inner Liste
//				return null;
//			}
//			if(comp == 0){
//				return j;
//			}
//		}
//		// den Rest noch anschauen:
//		for(int i = size-rest; i < size; i++){
//			FinalIDX l = finalDict.get(i);
//			if(l.name.equals(term)){
//				return l;
//			}
//		}
		return null;
	}

	private static int determineSkipWidth(AVLTree<FinalIDX> finalDict) {
//		if(finalDict.size() > 4){
//			int ret = finalDict.size()/10;
//			if (ret == 0)
//				ret = 1;
//			return ret;
//		}else{
//			return 1;
//		}
		return 4;
	}

	@SuppressWarnings("unused")
	private static String readFile(String filename)
	{
		String content = null;
		   File file = new File(filename); //for ex foo.txt
		   try {
		       FileReader reader = new FileReader(file);
		       char[] chars = new char[(int) file.length()];
		       reader.read(chars);
		       content = new String(chars);
		       reader.close();
		   } catch (IOException e) {
		       e.printStackTrace();
		   }
		   return content;
	}

}
